package com.ruoyi.asset.service.impl;

import java.util.Comparator;
import java.util.Date;
import java.util.List;

import com.ruoyi.asset.domain.*;
import com.ruoyi.asset.mapper.AssetFlowMapper;
import com.ruoyi.asset.mapper.AssetFlowTypeMapper;
import com.ruoyi.asset.service.IAssetFlowStepService;
import com.ruoyi.asset.service.IAssetFlowTypeService;
import com.ruoyi.common.core.domain.entity.SysUser;
import com.ruoyi.common.exception.ServiceException;
import com.ruoyi.common.utils.SecurityUtils;
import com.ruoyi.common.utils.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import com.ruoyi.asset.mapper.AssetFlowCheckMapper;
import com.ruoyi.asset.service.IAssetFlowCheckService;
import org.springframework.transaction.annotation.Transactional;

/**
 * 审核流程Service业务层处理
 * 
 * @author yepanpan
 * @date 2024-12-20
 */
@Service
public class AssetFlowCheckServiceImpl implements IAssetFlowCheckService 
{
    @Autowired
    private AssetFlowCheckMapper assetFlowCheckMapper;

    @Autowired
    private AssetFlowMapper assetFlowMapper;

    @Autowired
    private IAssetFlowTypeService assetFlowTypeService;

    @Autowired
    private IAssetFlowStepService assetFlowStepService;

    /**
     * 查询审核流程
     * 
     * @param id 审核流程主键
     * @return 审核流程
     */
    @Override
    public AssetFlowCheck selectAssetFlowCheckById(Long id)
    {
        AssetFlowCheck assetFlowCheck = assetFlowCheckMapper.selectAssetFlowCheckById(id);
        if(assetFlowCheck != null){
            assetFlowCheck.setFlow(assetFlowMapper.selectAssetFlowById(assetFlowCheck.getFlowId()));
        }
        return assetFlowCheck;
    }

    /**
     * 查询审核流程列表
     * 
     * @param assetFlowCheck 审核流程
     * @return 审核流程
     */
    @Override
    public List<AssetFlowCheck> selectAssetFlowCheckList(AssetFlowCheck assetFlowCheck)
    {
        List<AssetFlowCheck> list = assetFlowCheckMapper.selectAssetFlowCheckList(assetFlowCheck);
        if(StringUtils.isEmpty(list)){
            return list;
        }

        for(AssetFlowCheck row:list){
            row.setFlow(assetFlowMapper.selectAssetFlowById(row.getFlowId()));
        }
        return list;
    }

    /**
     * 提交审核流程
     *
     * @param flowId 工单主键
     * @return 结果
     */
    @Override
    @Transactional
    public int submitAssetFlowCheck(Long flowId){
        AssetFlow assetFlow = assetFlowMapper.selectAssetFlowById(flowId);
        if(assetFlow == null){
            throw new ServiceException("流程工单不存在");
        }

        List<AssetFlowStep> stepList = assetFlowStepService.selectAssetFlowStepList(assetFlow.getTypeId());
        stepList.sort(Comparator.comparingInt(AssetFlowStep::getSorts));
        List<SysUser> userList = null;
        AssetFlowStep step = null;
        for(AssetFlowStep assetFlowStep:stepList){
            userList = assetFlowStepService.selectStepUser(assetFlow.getTypeId(), assetFlowStep.getId(), assetFlow.getUserId());
            if(StringUtils.isNotEmpty(userList)){
                step = assetFlowStep;
                break;
            }
        }
        if(step == null){
            throw new ServiceException("流程配置有误，未找到审核人");
        }

        AssetFlowCheck assetFlowCheck = new AssetFlowCheck();
        assetFlowCheck.setFlowId(flowId);
        assetFlowCheck.setStepId(step.getId());
        assetFlowCheck.setFlowTime(new Date());
        assetFlowCheck.setCheckStatus(FlowCheck.CHECK_UNDO);
        for(SysUser user:userList){
            assetFlowCheck.setId(null);
            assetFlowCheck.setCheckUserId(user.getUserId());
            assetFlowCheckMapper.insertAssetFlowCheck(assetFlowCheck);
        }
        //标记开始审核中
        assetFlow.setFlowStatus(AssetFlow.STATUS_CHECK);
        return assetFlowMapper.updateAssetFlow(assetFlow);
    }

    /**
     * 批量审核
     *
     * @param flowCheck 审核对象
     * @return 结果
     */
    @Override
    public int batchCheckAssetFlow(FlowCheck flowCheck){
        if(StringUtils.isEmpty(flowCheck.getIds())){
            throw new ServiceException("至少要选择一个审核工单");
        }

        SysUser sysUser = SecurityUtils.getLoginUser().getUser();

        String comment = flowCheck.getCheckStatus().equalsIgnoreCase(FlowCheck.CHECK_AGREE) ? "批量通过" : "批量不通过";
        int ret = 0;
        for(Long id: flowCheck.getIds()){
            AssetFlowCheck assetFlowCheck = assetFlowCheckMapper.selectAssetFlowCheckById(id);
            AssetFlow assetFlow = assetFlowMapper.selectAssetFlowById(assetFlowCheck.getFlowId());

            //先将其他人的审核流程忽略
            ret += assetFlowCheckMapper.ignoreAssetFlowCheck(assetFlowCheck.getFlowId(), sysUser.getUserId());

            //再更新审核流程
            assetFlowCheck.setCheckTime(new Date());
            assetFlowCheck.setCheckUserName(sysUser.getNickName());
            assetFlowCheck.setCheckComment(comment);
            assetFlowCheck.setCheckStatus(flowCheck.getCheckStatus());
            ret += assetFlowCheckMapper.updateAssetFlowCheck(assetFlowCheck);

            //最后更新工单
            if(flowCheck.getCheckStatus().equalsIgnoreCase(FlowCheck.CHECK_AGREE)) {
               passCheck(assetFlow, assetFlowStepService.selectAssetFlowStepById(assetFlowCheck.getStepId()));
            }else{
                //不通过
                assetFlow.setFlowStatus(AssetFlow.STATUS_SCRAP);
            }
            assetFlow.setCheckStatus(flowCheck.getCheckStatus());
            ret += assetFlowMapper.updateAssetFlow(assetFlow);
        }
        return ret;
    }

    /**
     * 批量审核
     *
     * @param flowCheck 审核对象
     * @return 结果
     */
    @Transactional
    @Override
    public int checkAssetFlow(FlowCheck flowCheck){
        AssetFlowCheck assetFlowCheck = assetFlowCheckMapper.selectAssetFlowCheckById(flowCheck.getId());
        if(assetFlowCheck == null || !assetFlowCheck.getCheckStatus().equalsIgnoreCase(FlowCheck.CHECK_UNDO)){
            throw new ServiceException("工单不存在或者不需要审核");
        }
        AssetFlow assetFlow = assetFlowMapper.selectAssetFlowById(assetFlowCheck.getFlowId());
        if(assetFlow == null){
            throw new ServiceException("流程工单不存在");
        }

        int ret = 0;
        SysUser sysUser = SecurityUtils.getLoginUser().getUser();

        //先将其他人的审核流程忽略
        ret += assetFlowCheckMapper.ignoreAssetFlowCheck(assetFlowCheck.getFlowId(), sysUser.getUserId());

        //不同意就终止流程
        if(flowCheck.getCheckStatus().equalsIgnoreCase(FlowCheck.CHECK_DISAGREE)){
            assetFlow.setFlowStatus(AssetFlow.STATUS_SCRAP);
            assetFlow.setCheckStatus(flowCheck.getCheckStatus());
        }else if(flowCheck.getCheckStatus().equalsIgnoreCase(FlowCheck.CHECK_AGREE)){
            //同意
            passCheck(assetFlow, assetFlowStepService.selectAssetFlowStepById(assetFlowCheck.getStepId()));
        }
        ret += assetFlowMapper.updateAssetFlow(assetFlow);

        //标记审核记录
        assetFlowCheck.setCheckUserName(sysUser.getNickName());
        assetFlowCheck.setCheckTime(new Date());
        assetFlowCheck.setCheckStatus(flowCheck.getCheckStatus());
        assetFlowCheck.setCheckComment(flowCheck.getCheckComment());
        ret += assetFlowCheckMapper.updateAssetFlowCheck(assetFlowCheck);

        return ret;
    }

    /**
     * 审核通过的操作。判断是结束流程还是继续下个节点审核
     * @param assetFlow
     * @param currentStep
     */
    public void passCheck(AssetFlow assetFlow, AssetFlowStep currentStep){
        AssetFlowStep fsc = new AssetFlowStep();
        fsc.setTypeId(assetFlow.getTypeId());
        List<AssetFlowStep> stepList = assetFlowStepService.selectAssetFlowStepList(fsc);
        stepList.sort(Comparator.comparingInt(AssetFlowStep::getSorts));
        List<SysUser> userList = null;
        AssetFlowStep step = null;
        //计算下一步和用户
        for(AssetFlowStep assetFlowStep:stepList){
            if(assetFlowStep.getSorts() <= currentStep.getSorts()){
                continue;
            }
            userList = assetFlowStepService.selectStepUser(assetFlow.getTypeId(), assetFlowStep.getId(), SecurityUtils.getUserId());
            if(StringUtils.isNotEmpty(userList)){
                step = assetFlowStep;
                break;
            }
        }
        if(step == null){
            //审核通过
            AssetFlowType assetFlowType = assetFlowTypeService.selectAssetFlowTypeById(assetFlow.getTypeId());
            if(assetFlowType.getCode().equalsIgnoreCase(AssetFlow.TYPE_PURCHASE)) {
                assetFlow.setFlowStatus(AssetFlow.STATUS_UN_IN);
            }else{
                assetFlow.setFlowStatus(AssetFlow.STATUS_UN_OUT);
            }
            assetFlow.setCheckStatus(FlowCheck.CHECK_AGREE);
        }else{
            //继续审核
            AssetFlowCheck assetFlowCheck = new AssetFlowCheck();
            assetFlowCheck.setFlowId(assetFlow.getId());
            assetFlowCheck.setStepId(step.getId());
            assetFlowCheck.setFlowTime(new Date());
            assetFlowCheck.setCheckStatus(FlowCheck.CHECK_UNDO);
            for(SysUser user:userList){
                assetFlowCheck.setId(null);
                assetFlowCheck.setCheckUserId(user.getUserId());
                assetFlowCheckMapper.insertAssetFlowCheck(assetFlowCheck);
            }
        }
    }

    /**
     * 新增审核流程
     * 
     * @param assetFlowCheck 审核流程
     * @return 结果
     */
    @Override
    @Transactional
    public int insertAssetFlowCheck(AssetFlowCheck assetFlowCheck)
    {
        AssetFlow assetFlow = assetFlowMapper.selectAssetFlowById(assetFlowCheck.getFlowId());
        if(assetFlow == null){
            throw new ServiceException("流程工单不存在");
        }

        //标记开始审核中
        assetFlow.setFlowStatus(AssetFlow.STATUS_CHECK);
        assetFlowMapper.updateAssetFlow(assetFlow);

        assetFlowCheck.setFlowTime(new Date());
        assetFlowCheck.setCheckStatus(FlowCheck.CHECK_UNDO);
        return assetFlowCheckMapper.insertAssetFlowCheck(assetFlowCheck);
    }

    /**
     * 修改审核流程
     * 
     * @param assetFlowCheck 审核流程
     * @return 结果
     */
    @Override
    @Transactional
    public int updateAssetFlowCheck(AssetFlowCheck assetFlowCheck)
    {
        return assetFlowCheckMapper.updateAssetFlowCheck(assetFlowCheck);
    }

    /**
     * 批量删除审核流程
     * 
     * @param ids 需要删除的审核流程主键
     * @return 结果
     */
    @Override
    public int deleteAssetFlowCheckByIds(Long[] ids)
    {
        return assetFlowCheckMapper.deleteAssetFlowCheckByIds(ids);
    }

    /**
     * 删除审核流程信息
     * 
     * @param id 审核流程主键
     * @return 结果
     */
    @Override
    public int deleteAssetFlowCheckById(Long id)
    {
        return assetFlowCheckMapper.deleteAssetFlowCheckById(id);
    }
}
